package com.schoolComments.utils.lock;

import org.springframework.data.redis.core.StringRedisTemplate;

import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * @author 马园博
 * @date 2023/05/04/12:07
 * @Project hm-dianping
 **/
public class ILockImpl implements ILock{
    //解决误删问题 不同的前缀表明不同的服务器 一个前缀代表一个服务器(这样就不会有不同的服务器 但相同的线程id和相同的用户之间误删的情况)
    private static final String ID_PREFIX = UUID.randomUUID()+"-";
    //公共前缀
    private static final String KEY_PREFIX = "lock:";
    private StringRedisTemplate stringRedisTemplate;
    //锁的名字(key值)
    private String name;

    public ILockImpl(StringRedisTemplate stringRedisTemplate, String name) {
        this.stringRedisTemplate = stringRedisTemplate;
        this.name = name;
    }

    @Override
    public boolean getLock(long timeoutSec) {
        //获取当前线程id作为锁的value
        String threadID = String.valueOf(Thread.currentThread().getId());
        Boolean success = stringRedisTemplate.opsForValue().setIfAbsent(KEY_PREFIX+name, ID_PREFIX+threadID, timeoutSec, TimeUnit.SECONDS);
        //这样返回是为了防止Boolean类型有时为空而造成麻烦 返回包装类可以这样处理避免null
        return Boolean.TRUE.equals(success);
    }

    @Override
    public void unlock() {
        String threadID = String.valueOf(Thread.currentThread().getId());
        if(stringRedisTemplate.opsForValue().get(KEY_PREFIX+name).equals(ID_PREFIX+threadID)){
            //一致才能释放锁 不一致说明是别人的锁 不能释放
            stringRedisTemplate.delete(KEY_PREFIX+name);
        }
    }
}
